#include "CMainDialogImpl.h"
//
main_dialog_impl::main_dialog_impl( QWidget * parent, Qt::WFlags f) 
	: QDialog(parent, f)
{
	begin_style = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" \
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" \
"p, li { white-space: pre-wrap; }\n </style></head><body style=\" font-family:'DejaVu Serif'; font-size:10pt; font-weight:400; font-style:normal;\">\n" \
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:16pt; font-weight:600;\">";
	end_style = "</span></p></body></html>";
	setupUi(this);
}
//

void main_dialog_impl::on_open_compress_button_clicked()
{
	QString file_name = QFileDialog::getOpenFileName(this,QString::fromUtf8("Открыть для сжатия"),"./","All (*)");
	data_compress_edit->setText(file_name);
	// Сжатие доступно, если выбраны исходный и результирующий файл и эти файлы не совпадают
	if(!file_name.isEmpty() && !res_compress_edit->text().isEmpty()
		&& res_compress_edit->text() != data_compress_edit->text())
			compress_button->setEnabled(true);
	else
		compress_button->setEnabled(false);
}

void main_dialog_impl::on_save_compress_button_clicked()
{
	QString file_name = QFileDialog::getSaveFileName(this,QString::fromUtf8("Сохранить результат сжатия в"),"./","All (*)");
	res_compress_edit->setText(file_name);
	// Сжатие доступно, если выбраны исходный и результирующий файл и эти файлы не совпадают
	if(!file_name.isEmpty() && !data_compress_edit->text().isEmpty()
		&& res_compress_edit->text() != data_compress_edit->text())
			compress_button->setEnabled(true);
	else
		compress_button->setEnabled(false);
}

void main_dialog_impl::on_compress_button_clicked()
{
	compress_info->setText(begin_style + QString::fromUtf8("Сжатие...") + end_style);
	compress_button->setEnabled(false);
	compress_info->repaint();
	compress_button->repaint();
	
	/* С помощью QtConcurrent выделяем функцию ассемблерного модуля в отдельную нить,
	результат которой забираем с помощью объекта класса QFuture. Пока дочерняя нить будет выполняться - будем
	выводить иллюстрации протекания процесса обработки данных (с помощью прогрессбара) */
	QFuture<unsigned char> future = QtConcurrent::run(
	&haffman_compress,data_compress_edit->text().toLocal8Bit(),res_compress_edit->text().toLocal8Bit()
	);
	int tic = 0;
	while(future.isRunning())
	{
		QTest::qSleep(150);
		compress_progress_bar->setValue(tic);
		tic++;
		if(tic == 100)
		{
			tic = 0;
			compress_progress_bar->setInvertedAppearance(!compress_progress_bar->invertedAppearance());
		}
		compress_progress_bar->repaint();
		compress_info->repaint();
	}
	compress_progress_bar->setInvertedAppearance(false);
	compress_progress_bar->setValue(0);
	compress_info->setText(begin_style +
			get_error_description_rus(
			future.result()
			) + end_style);
			
	compress_button->setEnabled(true);
}

void main_dialog_impl::on_open_decompress_button_clicked()
{
	QString file_name = QFileDialog::getOpenFileName(this,QString::fromUtf8("Открыть для декомпрессии"),"./","All (*)");
	data_decompress_edit->setText(file_name);
	// Декомпрессия доступна, если выбраны исходный и результирующий файл и эти файлы не совпадают
	if(!file_name.isEmpty() && !res_decompress_edit->text().isEmpty()
		&& res_decompress_edit->text() != data_decompress_edit->text())
			decompress_button->setEnabled(true);
	else
		decompress_button->setEnabled(false);
}

void main_dialog_impl::on_save_decompress_button_clicked()
{
	QString file_name = QFileDialog::getSaveFileName(this,QString::fromUtf8("Сохранить результат декомпрессии в"),"./","All (*)");
	res_decompress_edit->setText(file_name);
	// Декомпрессия доступна, если выбраны исходный и результирующий файл и эти файлы не совпадают
	if(!file_name.isEmpty() && !data_decompress_edit->text().isEmpty()
		&& res_decompress_edit->text() != data_decompress_edit->text())
			decompress_button->setEnabled(true);
	else
		decompress_button->setEnabled(false);
}

void main_dialog_impl::on_decompress_button_clicked()
{
	decompress_info->setText(begin_style + QString::fromUtf8("Декомпрессия...") + end_style);
	decompress_button->setEnabled(false);
	decompress_info->repaint();
	decompress_button->repaint();
	
	/* С помощью QtConcurrent выделяем функцию ассемблерного модуля в отдельную нить,
	результат которой забираем с помощью объекта класса QFuture. Пока дочерняя нить будет выполняться - будем
	выводить иллюстрации протекания процесса обработки данных (с помощью прогрессбара) */
	QFuture<unsigned char> future = QtConcurrent::run(
	&haffman_decompress,data_decompress_edit->text().toLocal8Bit(),res_decompress_edit->text().toLocal8Bit()
	);
	int tic = 0;
	while(future.isRunning())
	{
		QTest::qSleep(150);
		decompress_progress_bar->setValue(tic);
		tic++;
		if(tic == 100)
		{
			tic = 0;
			decompress_progress_bar->setInvertedAppearance(!decompress_progress_bar->invertedAppearance());
		}
		decompress_progress_bar->repaint();
		decompress_info->repaint();
	}
	decompress_progress_bar->setInvertedAppearance(false);
	decompress_progress_bar->setValue(0);
	decompress_info->setText(begin_style +
			get_error_description_rus(
			future.result()
			) + end_style);
			
	decompress_button->setEnabled(true);
}

QString main_dialog_impl::get_error_description_rus(unsigned char error_code)
{
	QString rez;
	switch(error_code)
	{
		case 0:
		{
			rez = QString::fromUtf8("Успех");
			break;
		}
		case C_close_write_error:
		{
			rez = QString::fromUtf8("Невозможно закрыть сжатый файл после записи");
			break;
		}
		case C_open_write_error:
		{
			rez = QString::fromUtf8("Невозможно открыть сжатый файл для записи");
			break;			
		}
		case CF_open_read_error:
		{
			rez = QString::fromUtf8("Невозможно открыть сжимаемый файл для чтения,<br>однако в прошлом было возможно");
			break;
		}
		case CF_close_read_error:
		{
			rez = QString::fromUtf8("Невозможно закрыть сжимаемый файл после чтения,<br>однако в прошлом было возможно");
			break;
		}
		case CCA_overflow_error:
		{
			rez = QString::fromUtf8("Переполнение. Файл слишком большой для сжатия");
			break;
		}
		case RIF_open_read_error:
		{
			rez = QString::fromUtf8("Невозможно открыть сжимаемый файл для чтения");
			break;
		}
		case RIF_close_read_error:
		{
			rez = QString::fromUtf8("Невозможно закрыть сжимаемый файл после чтения");
			break;
		}
		case CL_malloc_error:
		{
			rez = QString::fromUtf8("Ошибка при выделении памяти");
			break;
		}
		case D_open_read_error:
		{
			rez = QString::fromUtf8("Невозможно открыть сжатый файл для чтения");
			break;
		}
		case D_close_read_error:
		{
			rez = QString::fromUtf8("Невозможно закрыть сжатый файл после чтения");
			break;
		}
		case RTSENFF_read_file_too_small:
		{
			rez = QString::fromUtf8("Исходный сжатый файл слишком мал.<br>Повреждена таблица восстановления дерева Хаффмана.<br>Сжатое содержимое отсутствует");
			break;
		}
		case DF_open_write_error:
		{
			rez = QString::fromUtf8("Невозможно открыть декомпрессированный файл<br>для записи");
			break;
		}
		case DF_close_write_error:
		{
			rez = QString::fromUtf8("Невозможно закрыть декомпрессированный файл<br>после записи");
			break;
		}
		case DF_read_file_too_small:
		{
			rez = QString::fromUtf8("Таблица восстановления дерева Хаффмана корректна,<br>однако в файле недостаточно сжатого содержимого,<br>чтобы восстановить исходный файл");
			break;
		}
		case CL_null_list:
		{
			rez = QString::fromUtf8("Входной файл - пуст");
			break;
		}
		case RIF_read_error:
		{
			rez = QString::fromUtf8("Невозможно прочитать сжимаемый файл");
			break;
		}
		case PT_write_error:
		{
			rez = QString::fromUtf8("Невозможно записать таблицу количеств вхождений<br>символов в сжатый файл");
			break;
		}
		case CF_read_error:
		{
			rez = QString::fromUtf8("Невозможно прочитать сжимаемый файл");
			break;
		}
		case CF_write_error_1:
		{
			rez = QString::fromUtf8("Невозможно записать в результирующий файл при сжатии");
			break;
		}
		case CF_write_error_2:
		{
			rez = QString::fromUtf8("Невозможно записать в результирующий файл при сжатии");
			break;
		}
		case DF_read_error:
		{
			rez = QString::fromUtf8("Невозможно прочитать сжатый файл");
			break;
		}
		case DF_write_error_1:
		{
			rez = QString::fromUtf8("Невозможно записать в результирующий файл при<br>декомпресии");
			break;
		}
		case DF_write_error_2:
		{
			rez = QString::fromUtf8("Невозможно записать в результирующий файл при<br>декомпресии");
			break;
		}
		case DF_decompress_file_size_error:
		{
			rez = QString::fromUtf8("Некорректный размер декомпрессированного файла");
			break;
		}
		default:
		{
			rez = QString::fromUtf8("Неизвестная ошибка");
		}
	}
	return rez;
}
